package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"errors"
	"fmt"
	"os"
	"time"
)

type License struct {
	ExpiryTime string `json:"expiry_time"` // 过期时间
	Signer     string `json:"signer"`      // 签名人
	Email      string `json:"email"`       // 邮箱
	Signature  string `json:"signature"`   // 签名
}

func main() {
	// 生成或加载密钥对
	privateKeyFile := "private.pem"
	publicKeyFile := "public.pem"

	// 检查是否存在私钥文件，如果不存在则生成新的密钥对
	if _, err := os.Stat(privateKeyFile); os.IsNotExist(err) {
		fmt.Println("Private key not found. Generating new key pair...")
		err := generateKeyPair(privateKeyFile, publicKeyFile)
		if err != nil {
			fmt.Printf("Failed to generate key pair: %v\n", err)
			return
		}
		fmt.Println("Key pair generated successfully.")
	}

	// 加载私钥
	privateKey, err := loadPrivateKey(privateKeyFile)
	if err != nil {
		fmt.Printf("Failed to load private key: %v\n", err)
		return
	}

	// 设置 license 数据
	expiryTime := time.Now().Add(300 * 24 * time.Hour).Format(time.RFC3339) // 300天后过期
	signer := "Yang Xiang"
	email := "1487442089@qq.com"

	// 创建 license 数据
	licenseData := License{
		ExpiryTime: expiryTime,
		Signer:     signer,
		Email:      email,
	}

	// 序列化数据为 JSON
	data, err := json.Marshal(licenseData)
	if err != nil {
		fmt.Printf("Failed to marshal license data: %v\n", err)
		return
	}

	// 使用私钥对数据进行签名
	hash := sha256.Sum256(data)
	signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:])
	if err != nil {
		fmt.Printf("Failed to sign data: %v\n", err)
		return
	}

	// 将签名编码为 Base64
	licenseData.Signature = base64.StdEncoding.EncodeToString(signature)

	// 将 license 写入文件
	licenseFile := "license.lic"
	licenseJSON, err := json.MarshalIndent(licenseData, "", "  ") // 使用 MarshalIndent 美化输出
	if err != nil {
		fmt.Printf("Failed to marshal license data: %v\n", err)
		return
	}

	err = os.WriteFile(licenseFile, licenseJSON, 0644)
	if err != nil {
		fmt.Printf("Failed to write license file: %v\n", err)
		return
	}

	fmt.Println("License file generated successfully.")
}

// 生成 RSA 密钥对并保存到文件
func generateKeyPair(privateKeyFile, publicKeyFile string) error {
	// 生成 RSA 密钥对
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return fmt.Errorf("failed to generate private key: %w", err)
	}

	// 保存私钥到文件
	privateKeyBytes := pem.EncodeToMemory(&pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
	})
	if err := os.WriteFile(privateKeyFile, privateKeyBytes, 0600); err != nil {
		return fmt.Errorf("failed to write private key file: %w", err)
	}

	// 生成公钥
	publicKeyBytes, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
	if err != nil {
		return fmt.Errorf("failed to marshal public key: %w", err)
	}

	// 保存公钥到文件
	publicKeyPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "PUBLIC KEY",
		Bytes: publicKeyBytes,
	})
	if err := os.WriteFile(publicKeyFile, publicKeyPEM, 0644); err != nil {
		return fmt.Errorf("failed to write public key file: %w", err)
	}

	return nil
}

// 加载私钥
func loadPrivateKey(file string) (*rsa.PrivateKey, error) {
	keyBytes, err := os.ReadFile(file)
	if err != nil {
		return nil, err
	}
	block, _ := pem.Decode(keyBytes)
	if block == nil {
		return nil, errors.New("failed to decode PEM block")
	}
	return x509.ParsePKCS1PrivateKey(block.Bytes)
}
